//
// Created by starry on 2025/5/29.
//

#ifndef CV_CAL_QRPICKDETECTOR_H
#define CV_CAL_QRPICKDETECTOR_H


#include <opencv2/core/mat.hpp>
#include <Result.h>
#include "card_params_info.h"
#include "rectangle_info.hpp"

class QRPickDetector {
public:
    QRPickDetector() = default;

    /**
     * @brief 检测图像中的二维码是否有效
     * @param inputImage 输入图像(BGR格式)
     * @return 是否检测到至少一个有效二维码
     */
    bool isContainsQRCode(const cv::Mat& inputImage);


    /**
     * @brief 获取比例系数值
     * @param qr_side 二维码边长
     * @param index 二维码索引
     * @return
     */
    double getScaleFactorValue(double qr_side, int index);


    /**
     * @brief 获取带标注的可视化图像
     *
     * @return
     */
    cv::Mat getMarkedImage();

    /**
     * @brief 在QR上绘制四个矩形框
     *
     * @param rectangles
     */
    void setRectangleInfo(const std::vector<RectangleInfo>& rectangles);


    /**
     * @brief 计算QR的参数数据
     */
    void generateQRParams();

    /**
     * @brief 处理单个二维码的ROI提取
     * @param qrCorners 二维码四个角点(顺序: TL, TR, BR, BL)
     * @param qrBottomToChannelCenter 二维码底部到channel中心距离
     *  @param width Channel宽度
     *  @param height Channel高度
     */
    void processSingleQR(const std::vector<cv::Point>& qrCorners, double qrBottomToChannelCenter, double width, double height);

    /**
     * @brief 处理偏移指定QR底边距离的点坐标
     * @param qrCorners
     * @param offset 需要计算的偏移距离列表
     * @param width
     * @param height
     * @param index BOX索引
     * @return
     */
    std::vector<cv::Point> processSingleQROffInstance(const std::vector<cv::Point>& qrCorners,
                                                      const double& offset,
                                                      const double& width,
                                                      const double& height,
                                                      const int& index);

    // Getter方法
    const std::vector<double>& getQrSideLengths() const;
    const cv::Mat& getExtractedROIs(int index) const;
    const cv::Mat& getMarkedImage() const;
    const std::vector<std::vector<cv::Point>>& getAllQrCorners() const;
    const std::vector<std::string>& getQrContents() const;

private:

    // 成员变量
    ZXing::Results m_results;                    // 二维码识别结果
    cv::Mat m_markedImage;                         // 带标注的可视化图像
    std::vector<cv::Mat> m_extractedROIs; // 提取的所有ROI区域
    std::vector<std::vector<cv::Point>> m_allQrCorners; // 所有二维码角点
    std::vector<double> m_qrSideLengths;           // 所有二维码的边长估算
    std::vector<std::string> m_qrContents;         // 所有二维码的文本内容

    /**
     * @brief 计算二维码四条边长并返回平均值
     * @param qrCorners 二维码四个角点（顺序必须为顺时针/逆时针连续）
     * @return 四条边的平均长度
     * @throws std::invalid_argument 当输入无效时抛出异常
     */
    double calculateAverageSideLength(const std::vector<cv::Point>& qrCorners);

    /**
     * @brief 在二维码边上绘制二维码内容
     *
     * @param image
     * @param qrContent
     * @param qrCorners
     */
    void displayQrContentOnSide(cv::Mat& image, const std::string& qrContent, const std::vector<cv::Point>& qrCorners);

};


#endif //CV_CAL_QRPICKDETECTOR_H
